Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

core/model/src/commonMain/kotlin/org/meshtastic/core/model/NodeInfo.kt 97ec245a70ef792e54a9e21a2d79c4832ced1d25 (97ec245a) Text, 9.77 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.model

Tff7b72import T7ee787org.meshtastic.core.common.util.CommonParcelable
Tff7b72import T7ee787org.meshtastic.core.common.util.CommonParcelize
Tff7b72import T7ee787org.meshtastic.core.common.util.bearing
Tff7b72import T7ee787org.meshtastic.core.common.util.latLongToMeter
Tff7b72import T7ee787org.meshtastic.core.common.util.nowSeconds
Tff7b72import T7ee787org.meshtastic.core.model.util.anonymize
Tff7b72import T7ee787org.meshtastic.core.model.util.onlineTimeThreshold
Tff7b72import T7ee787org.meshtastic.proto.Config
Tff7b72import T7ee787org.meshtastic.proto.HardwareModel

T8b949e//
T8b949e// model objects that directly map to the corresponding protobufs
T8b949e//

Tf0883e@CommonParcelize
Tff7b72data Tff7b72class T56d364MeshUserTb4b4b4(
Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3longNameTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3shortNameTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3hwModelTb4b4b4: Te6edf3HardwareModelTb4b4b4,
Tff7b72val Te6edf3isLicensedTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Tff7b72val Te6edf3roleTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommonParcelable Tb4b4b4{

Tff7b72override Tff7b72fun Td2a8fftoStringTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Ta5d6ff"Ta5d6ffMeshUser(id=Tffd700${Te6edf3idTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6fflongName=Tffd700${Te6edf3longNameTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffshortName=Tffd700${Te6edf3shortNameTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffhwModel=Tffd700$Te6edf3hwModelStringTa5d6ff, Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffisLicensed=Tffd700$Te6edf3isLicensedTa5d6ff, Ta5d6ff" Tff7b72+
Ta5d6ff"Ta5d6ffrole=Tffd700$Te6edf3roleTa5d6ff)Ta5d6ff"

T8b949e/** Create our model object from a protobuf. */
Tff7b72constructorTb4b4b4(
Te6edf3pTb4b4b4: Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3UserTb4b4b4,
Tb4b4b4) Tb4b4b4: Tff7b72thisTb4b4b4(Te6edf3pTb4b4b4.Te6edf3idTb4b4b4, Te6edf3pTb4b4b4.Te6edf3long_nameTb4b4b4, Te6edf3pTb4b4b4.Te6edf3short_nameTb4b4b4, Te6edf3pTb4b4b4.Te6edf3hw_modelTb4b4b4, Te6edf3pTb4b4b4.Te6edf3is_licensedTb4b4b4, Te6edf3pTb4b4b4.Te6edf3roleTb4b4b4.Te6edf3valueTb4b4b4)

T8b949e/**
* a string version of the hardware model, converted into pretty lowercase and changing _ to -, and p to dot or null
* if unset
*/
Tff7b72val Te6edf3hwModelStringTb4b4b4: Tffa657String?
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3hwModel Tff7b72=Tff7b72= Te6edf3HardwareModelTb4b4b4.Te6edf3UNSETTb4b4b4) Tb4b4b4{
Tff7b72null
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3hwModelTb4b4b4.Te6edf3nameTb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff'_'Tb4b4b4, Ta5d6ff'-'Tb4b4b4)Tb4b4b4.Te6edf3replaceTb4b4b4(Ta5d6ff'p'Tb4b4b4, Ta5d6ff'.'Tb4b4b4)Tb4b4b4.Te6edf3lowercaseTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@CommonParcelize
Tff7b72data Tff7b72class T56d364PositionTb4b4b4(
Tff7b72val Te6edf3latitudeTb4b4b4: Tffa657DoubleTb4b4b4,
Tff7b72val Te6edf3longitudeTb4b4b4: Tffa657DoubleTb4b4b4,
Tff7b72val Te6edf3altitudeTb4b4b4: Tffa657IntTb4b4b4,
Tff7b72val Te6edf3timeTb4b4b4: Tffa657Int Tff7b72= Te6edf3currentTimeTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// default to current time in secs (NOT MILLISECONDS!)
Tff7b72val Te6edf3satellitesInViewTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tff7b72val Te6edf3groundSpeedTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tff7b72val Te6edf3groundTrackTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4, T8b949e// "heading"
Tff7b72val Te6edf3precisionBitsTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommonParcelable Tb4b4b4{

Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e// / Convert to a double representation of degrees
Tff7b72fun Td2a8ffdegDTb4b4b4(Te6edf3iTb4b4b4: Tffa657IntTb4b4b4) Tff7b72= Te6edf3i Tff7b72* T79c0ff1e-7

Tff7b72fun Td2a8ffdegITb4b4b4(Te6edf3dTb4b4b4: Tffa657DoubleTb4b4b4) Tff7b72= Tb4b4b4(Te6edf3d Tff7b72* T79c0ff1Te6edf3e7Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)

Tff7b72fun Td2a8ffcurrentTimeTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nowSecondsTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e/**
* Create our model object from a protobuf. If time is unspecified in the protobuf, the provided default time will
* be used.
*/
Tff7b72constructorTb4b4b4(
Te6edf3positionTb4b4b4: Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3PositionTb4b4b4,
Te6edf3defaultTimeTb4b4b4: Tffa657Int Tff7b72= Te6edf3currentTimeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4: Tff7b72thisTb4b4b4(
T8b949e// We prefer the int version of lat/lon but if not available use the depreciated legacy version
Te6edf3degDTb4b4b4(Te6edf3positionTb4b4b4.Te6edf3latitude_i Tff7b72?: T79c0ff0Tb4b4b4)Tb4b4b4,
Te6edf3degDTb4b4b4(Te6edf3positionTb4b4b4.Te6edf3longitude_i Tff7b72?: T79c0ff0Tb4b4b4)Tb4b4b4,
Te6edf3positionTb4b4b4.Te6edf3altitude Tff7b72?: T79c0ff0Tb4b4b4,
Tff7b72if Tb4b4b4(Te6edf3positionTb4b4b4.Te6edf3time Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Te6edf3positionTb4b4b4.Te6edf3time Tff7b72else Te6edf3defaultTimeTb4b4b4,
Te6edf3positionTb4b4b4.Te6edf3sats_in_viewTb4b4b4,
Te6edf3positionTb4b4b4.Te6edf3ground_speed Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3positionTb4b4b4.Te6edf3ground_track Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3positionTb4b4b4.Te6edf3precision_bitsTb4b4b4,
Tb4b4b4)

T8b949e// / @return distance in meters to some other node (or null if unknown)
Tff7b72fun Td2a8ffdistanceTb4b4b4(Te6edf3oTb4b4b4: Te6edf3PositionTb4b4b4) Tff7b72= Te6edf3latLongToMeterTb4b4b4(Te6edf3latitudeTb4b4b4, Te6edf3longitudeTb4b4b4, Te6edf3oTb4b4b4.Te6edf3latitudeTb4b4b4, Te6edf3oTb4b4b4.Te6edf3longitudeTb4b4b4)

T8b949e// / @return bearing to the other position in degrees
Tff7b72fun Td2a8ffbearingTb4b4b4(Te6edf3oTb4b4b4: Te6edf3PositionTb4b4b4) Tff7b72= Te6edf3bearingTb4b4b4(Te6edf3latitudeTb4b4b4, Te6edf3longitudeTb4b4b4, Te6edf3oTb4b4b4.Te6edf3latitudeTb4b4b4, Te6edf3oTb4b4b4.Te6edf3longitudeTb4b4b4)

T8b949e// If GPS gives a crap position don't crash our app
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72fun Td2a8ffisValidTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657Boolean Tff7b72= Te6edf3latitude Tff7b72!Tff7b72= T79c0ff0.0 Tff7b72&Tff7b72&
Te6edf3longitude Tff7b72!Tff7b72= T79c0ff0.0 Tff7b72&Tff7b72&
Tb4b4b4(Te6edf3latitude Tff7b72>Tff7b72= Tff7b72-T79c0ff9T79c0ff0 Tff7b72&Tff7b72& Te6edf3latitude Tff7b72<Tff7b72= T79c0ff9T79c0ff0.0Tb4b4b4) Tff7b72&Tff7b72&
Tb4b4b4(Te6edf3longitude Tff7b72>Tff7b72= Tff7b72-T79c0ff1T79c0ff8T79c0ff0 Tff7b72&Tff7b72& Te6edf3longitude Tff7b72<Tff7b72= T79c0ff1T79c0ff8T79c0ff0Tb4b4b4)

Tff7b72override Tff7b72fun Td2a8fftoStringTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tff7b72=
Ta5d6ff"Ta5d6ffPosition(lat=Tffd700${Te6edf3latitudeTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, lon=Tffd700${Te6edf3longitudeTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, alt=Tffd700${Te6edf3altitudeTb4b4b4.Te6edf3anonymizeTffd700}Ta5d6ff, time=Tffd700$Te6edf3timeTa5d6ff)Ta5d6ff"
Tb4b4b4}

Tf0883e@CommonParcelize
Tff7b72data Tff7b72class T56d364DeviceMetricsTb4b4b4(
Tff7b72val Te6edf3timeTb4b4b4: Tffa657Int Tff7b72= Te6edf3currentTimeTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// default to current time in secs (NOT MILLISECONDS!)
Tff7b72val Te6edf3batteryLevelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tff7b72val Te6edf3voltageTb4b4b4: Tffa657FloatTb4b4b4,
Tff7b72val Te6edf3channelUtilizationTb4b4b4: Tffa657FloatTb4b4b4,
Tff7b72val Te6edf3airUtilTxTb4b4b4: Tffa657FloatTb4b4b4,
Tff7b72val Te6edf3uptimeSecondsTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommonParcelable Tb4b4b4{
Tff7b72companion Tff7b72object Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72fun Td2a8ffcurrentTimeTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nowSecondsTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e/** Create our model object from a protobuf. */
Tff7b72constructorTb4b4b4(
Te6edf3pTb4b4b4: Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3DeviceMetricsTb4b4b4,
Te6edf3telemetryTimeTb4b4b4: Tffa657Int Tff7b72= Te6edf3currentTimeTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4) Tb4b4b4: Tff7b72thisTb4b4b4(
Te6edf3telemetryTimeTb4b4b4,
Te6edf3pTb4b4b4.Te6edf3battery_level Tff7b72?: T79c0ff0Tb4b4b4,
Te6edf3pTb4b4b4.Te6edf3voltage Tff7b72?: T79c0ff0fTb4b4b4,
Te6edf3pTb4b4b4.Te6edf3channel_utilization Tff7b72?: T79c0ff0fTb4b4b4,
Te6edf3pTb4b4b4.Te6edf3air_util_tx Tff7b72?: T79c0ff0fTb4b4b4,
Te6edf3pTb4b4b4.Te6edf3uptime_seconds Tff7b72?: T79c0ff0Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tf0883e@CommonParcelize
Tff7b72data Tff7b72class T56d364EnvironmentMetricsTb4b4b4(
Tff7b72val Te6edf3timeTb4b4b4: Tffa657Int Tff7b72= Te6edf3currentTimeTb4b4b4(Tb4b4b4)Tb4b4b4, T8b949e// default to current time in secs (NOT MILLISECONDS!)
Tff7b72val Te6edf3temperatureTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3relativeHumidityTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3soilTemperatureTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3soilMoistureTb4b4b4: Tffa657Int?Tb4b4b4,
Tff7b72val Te6edf3barometricPressureTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3gasResistanceTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3voltageTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3currentTb4b4b4: Tffa657Float?Tb4b4b4,
Tff7b72val Te6edf3iaqTb4b4b4: Tffa657Int?Tb4b4b4,
Tff7b72val Te6edf3luxTb4b4b4: Tffa657Float? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72val Te6edf3uvLuxTb4b4b4: Tffa657Float? Tff7b72= Tff7b72nullTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommonParcelable Tb4b4b4{
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72fun Td2a8ffcurrentTimeTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3nowSecondsTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)

Tff7b72fun Td2a8fffromTelemetryProtoTb4b4b4(Te6edf3protoTb4b4b4: Te6edf3orgTb4b4b4.Te6edf3meshtasticTb4b4b4.Te6edf3protoTb4b4b4.Te6edf3EnvironmentMetricsTb4b4b4, Te6edf3timeTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3EnvironmentMetrics Tff7b72=
Te6edf3EnvironmentMetricsTb4b4b4(
Te6edf3temperature Tff7b72= Te6edf3protoTb4b4b4.Te6edf3temperatureTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3relativeHumidity Tff7b72= Te6edf3protoTb4b4b4.Te6edf3relative_humidityTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tff7b72&Tff7b72& Tffa657it Tff7b72!Tff7b72= T79c0ff0.0f Tb4b4b4}Tb4b4b4,
Te6edf3soilTemperature Tff7b72= Te6edf3protoTb4b4b4.Te6edf3soil_temperatureTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3soilMoisture Tff7b72= Te6edf3protoTb4b4b4.Te6edf3soil_moistureTff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657it Tff7b72!Tff7b72= Tffa657IntTb4b4b4.Te6edf3MIN_VALUE Tb4b4b4}Tb4b4b4,
Te6edf3barometricPressure Tff7b72= Te6edf3protoTb4b4b4.Te6edf3barometric_pressureTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3gasResistance Tff7b72= Te6edf3protoTb4b4b4.Te6edf3gas_resistanceTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3voltage Tff7b72= Te6edf3protoTb4b4b4.Te6edf3voltageTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3current Tff7b72= Te6edf3protoTb4b4b4.Te6edf3currentTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3iaq Tff7b72= Te6edf3protoTb4b4b4.Te6edf3iaqTff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657it Tff7b72!Tff7b72= Tffa657IntTb4b4b4.Te6edf3MIN_VALUE Tb4b4b4}Tb4b4b4,
Te6edf3lux Tff7b72= Te6edf3protoTb4b4b4.Te6edf3luxTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3uvLux Tff7b72= Te6edf3protoTb4b4b4.Te6edf3uv_luxTff7b72?.Te6edf3takeIf Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3isNaNTb4b4b4(Tb4b4b4) Tb4b4b4}Tb4b4b4,
Te6edf3time Tff7b72= Te6edf3timeTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tf0883e@CommonParcelize
Tff7b72data Tff7b72class T56d364NodeInfoTb4b4b4(
Tff7b72val Te6edf3numTb4b4b4: Tffa657IntTb4b4b4, T8b949e// This is immutable, and used as a key
Tff7b72var Te6edf3userTb4b4b4: Te6edf3MeshUser? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72var Te6edf3positionTb4b4b4: Te6edf3Position? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72var Te6edf3snrTb4b4b4: Tffa657Float Tff7b72= Tffa657FloatTb4b4b4.Te6edf3MAX_VALUETb4b4b4,
Tff7b72var Te6edf3rssiTb4b4b4: Tffa657Int Tff7b72= Tffa657IntTb4b4b4.Te6edf3MAX_VALUETb4b4b4,
Tff7b72var Te6edf3lastHeardTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4, T8b949e// the last time we've seen this node in secs since 1970
Tff7b72var Te6edf3deviceMetricsTb4b4b4: Te6edf3DeviceMetrics? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72var Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tff7b72var Te6edf3environmentMetricsTb4b4b4: Te6edf3EnvironmentMetrics? Tff7b72= Tff7b72nullTb4b4b4,
Tff7b72var Te6edf3hopsAwayTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4,
Tff7b72var Te6edf3nodeStatusTb4b4b4: Tffa657String? Tff7b72= Tff7b72nullTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3CommonParcelable Tb4b4b4{

Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3colorsTb4b4b4: Te6edf3PairTff7b72<Tffa657IntTb4b4b4, Tffa657IntTff7b72>
Tff7b72getTb4b4b4(Tb4b4b4) Tb4b4b4{ T8b949e// returns foreground and background @ColorInt for each 'num'
Tff7b72val Te6edf3r Tff7b72= Tb4b4b4(Te6edf3num Te6edf3and T79c0ff0Te6edf3xFF0000Tb4b4b4) Te6edf3shr T79c0ff1T79c0ff6
Tff7b72val Te6edf3g Tff7b72= Tb4b4b4(Te6edf3num Te6edf3and T79c0ff0Te6edf3x00FF00Tb4b4b4) Te6edf3shr T79c0ff8
Tff7b72val Te6edf3b Tff7b72= Te6edf3num Te6edf3and T79c0ff0Te6edf3x0000FF
Tff7b72val Te6edf3brightness Tff7b72= Tb4b4b4(Tb4b4b4(Te6edf3r Tff7b72* T79c0ff0.299Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3g Tff7b72* T79c0ff0.587Tb4b4b4) Tff7b72+ Tb4b4b4(Te6edf3b Tff7b72* T79c0ff0.114Tb4b4b4)Tb4b4b4) Tff7b72/ T79c0ff2T79c0ff5T79c0ff5
Tff7b72val Te6edf3foreground Tff7b72= Tff7b72if Tb4b4b4(Te6edf3brightness Tff7b72> T79c0ff0.5Tb4b4b4) T79c0ff0Te6edf3xFF000000Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Tff7b72else T79c0ff0Te6edf3xFFFFFFFFTb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3background Tff7b72= Tb4b4b4(T79c0ff0Te6edf3xFF Te6edf3shl T79c0ff2T79c0ff4Tb4b4b4) Te6edf3or Tb4b4b4(Te6edf3r Te6edf3shl T79c0ff1T79c0ff6Tb4b4b4) Te6edf3or Tb4b4b4(Te6edf3g Te6edf3shl T79c0ff8Tb4b4b4) Te6edf3or Te6edf3b
Tff7b72return Te6edf3foreground Te6edf3to Te6edf3background
Tb4b4b4}

Tff7b72val Te6edf3batteryLevel
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3deviceMetricsTff7b72?.Te6edf3batteryLevel

Tff7b72val Te6edf3voltage
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3deviceMetricsTff7b72?.Te6edf3voltage

Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffImplicitDefaultLocaleTa5d6ff"Tb4b4b4)
Tff7b72val Te6edf3batteryStr
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Tff7b72if Tb4b4b4(Te6edf3batteryLevel Tff7b72in T79c0ff1.Tb4b4b4.T79c0ff1T79c0ff0T79c0ff0Tb4b4b4) Ta5d6ff"Tffd700$Te6edf3batteryLevelTa5d6ff%Ta5d6ff" Tff7b72else Ta5d6ff"Ta5d6ff"

T8b949e/** true if the device was heard from recently */
Tff7b72val Te6edf3isOnlineTb4b4b4: Tffa657Boolean
Tff7b72getTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3lastHeard Tff7b72> Te6edf3onlineTimeThresholdTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e// / return the position if it is valid, else null
Tff7b72val Te6edf3validPositionTb4b4b4: Te6edf3Position?
Tff7b72getTb4b4b4(Tb4b4b4) Tb4b4b4{
Tff7b72return Te6edf3positionTff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isValidTb4b4b4(Tb4b4b4) Tb4b4b4}
Tb4b4b4}

T8b949e// / @return distance in meters to some other node (or null if unknown)
Tff7b72fun Td2a8ffdistanceTb4b4b4(Te6edf3oTb4b4b4: Te6edf3NodeInfo?Tb4b4b4)Tb4b4b4: Tffa657Int? Tb4b4b4{
Tff7b72val Te6edf3p Tff7b72= Te6edf3validPosition
Tff7b72val Te6edf3op Tff7b72= Te6edf3oTff7b72?.Te6edf3validPosition
Tff7b72return Tff7b72if Tb4b4b4(Te6edf3p Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3op Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Te6edf3pTb4b4b4.Te6edf3distanceTb4b4b4(Te6edf3opTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72null
Tb4b4b4}

T8b949e// / @return bearing to the other position in degrees
Tff7b72fun Td2a8ffbearingTb4b4b4(Te6edf3oTb4b4b4: Te6edf3NodeInfo?Tb4b4b4)Tb4b4b4: Tffa657Int? Tb4b4b4{
Tff7b72val Te6edf3p Tff7b72= Te6edf3validPosition
Tff7b72val Te6edf3op Tff7b72= Te6edf3oTff7b72?.Te6edf3validPosition
Tff7b72return Tff7b72if Tb4b4b4(Te6edf3p Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3op Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Te6edf3pTb4b4b4.Te6edf3bearingTb4b4b4(Te6edf3opTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Tff7b72else Tff7b72null
Tb4b4b4}

T8b949e// / @return a nice human readable string for the distance, or null for unknown
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72fun Td2a8ffdistanceStrTb4b4b4(Te6edf3oTb4b4b4: Te6edf3NodeInfo?Tb4b4b4, Te6edf3prefUnitsTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4) Tff7b72= Te6edf3distanceTb4b4b4(Te6edf3oTb4b4b4)Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3dist Tff7b72-Tff7b72>
Tff7b72when Tb4b4b4{
Te6edf3dist Tff7b72=Tff7b72= T79c0ff0 Tff7b72-Tff7b72> Tff7b72null

T8b949e// same point
Te6edf3prefUnits Tff7b72=Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DisplayConfigTb4b4b4.Te6edf3DisplayUnitsTb4b4b4.Te6edf3METRICTb4b4b4.Te6edf3value Tff7b72&Tff7b72& Te6edf3dist Tff7b72< T79c0ff1T79c0ff0T79c0ff0T79c0ff0 Tff7b72-Tff7b72> Ta5d6ff"Tffd700$Te6edf3distTa5d6ff mTa5d6ff"

Te6edf3prefUnits Tff7b72=Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DisplayConfigTb4b4b4.Te6edf3DisplayUnitsTb4b4b4.Te6edf3METRICTb4b4b4.Te6edf3value Tff7b72&Tff7b72& Te6edf3dist Tff7b72>Tff7b72= T79c0ff1T79c0ff0T79c0ff0T79c0ff0 Tff7b72-Tff7b72>
Ta5d6ff"Tffd700${Tb4b4b4(Te6edf3dist Tff7b72/ T79c0ff1T79c0ff0T79c0ff0Tb4b4b4)Tb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1T79c0ff0.0Tffd700}Ta5d6ff kmTa5d6ff"

Te6edf3prefUnits Tff7b72=Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DisplayConfigTb4b4b4.Te6edf3DisplayUnitsTb4b4b4.Te6edf3IMPERIALTb4b4b4.Te6edf3value Tff7b72&Tff7b72& Te6edf3dist Tff7b72< T79c0ff1T79c0ff6T79c0ff0T79c0ff9 Tff7b72-Tff7b72>
Ta5d6ff"Tffd700${Tb4b4b4(Te6edf3distTb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4) Tff7b72* T79c0ff3.281Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff ftTa5d6ff"

Te6edf3prefUnits Tff7b72=Tff7b72= Te6edf3ConfigTb4b4b4.Te6edf3DisplayConfigTb4b4b4.Te6edf3DisplayUnitsTb4b4b4.Te6edf3IMPERIALTb4b4b4.Te6edf3value Tff7b72&Tff7b72& Te6edf3dist Tff7b72>Tff7b72= T79c0ff1T79c0ff6T79c0ff0T79c0ff9 Tff7b72-Tff7b72>
Ta5d6ff"Tffd700${Tb4b4b4(Te6edf3dist Tff7b72/ T79c0ff1T79c0ff6T79c0ff0.9Tb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4) Tff7b72/ T79c0ff1T79c0ff0.0Tffd700}Ta5d6ff miTa5d6ff"

Tff7b72else Tff7b72-Tff7b72> Tff7b72null
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.09s